package ru.volgogradetzzz.display
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	public class BitmapScale9 extends Bitmap
	{
		private var _w:Number;
		private var _h:Number;
		
		private var _rect:Rectangle;
		private var _originalBD:BitmapData;
		
		private var _tempRect:Rectangle = new Rectangle();
		private var _tempMatrix:Matrix = new Matrix();
		
		private var _tempLeft:Number;
		private var _tempRight:Number;
		private var _tempTop:Number;
		private var _tempBottom:Number;
		
		private var _tempRatioSidesW:Number;
		private var _tempRatioMiddleW:Number;
		private var _tempRatioSidesH:Number;
		private var _tempRatioMiddleH:Number;
		
		public function BitmapScale9(bitmapData:BitmapData, rect:Rectangle, pixelSnapping:String = "auto", smoothing:Boolean = false)
		{
			super(bitmapData, pixelSnapping, smoothing);
			
			if (!bitmapData.rect.containsRect(rect))
			{
				throw(new RangeError('Указанный rect выходит за границы bitmapData.rect'));
			}
			
			_originalBD = bitmapData.clone();
			_rect = rect;
			
			_w = bitmapData.width;
			_h = bitmapData.height;
		}
		
		override public function set bitmapData(value:BitmapData):void 
		{
			_originalBD = value;
			
			createBitmapData();
		}
		
		override public function get width():Number
		{
			return _w;
		}
			
		override public function set width(value:Number):void
		{
			if (value == _w) return;
			
			_w = value < 1 ? 1 : value;
			
			createBitmapData();
		}
		
		override public function get height():Number
		{
			return _h;
		}
		
		override public function set height(value:Number):void
		{
			if (value == _h) return;
			
			_h = value < 1 ? 1 : value;
			
			createBitmapData();
		}
		
		private function createBitmapData():void
		{
			var newBD:BitmapData = new BitmapData(_w, _h, true, 0x00000000);
			newBD.lock();
			
			_tempLeft = _rect.x;
			_tempRight = _originalBD.width - _rect.x - _rect.width;
			_tempTop = _rect.y;
			_tempBottom = _originalBD.height - _rect.y - _rect.height;
			
			_tempRatioSidesW = _w / (_tempLeft + _tempRight);
			_tempRatioMiddleW = (_w - _tempLeft - _tempRight) / _rect.width;
			_tempRatioSidesH = _h / (_tempTop + _tempBottom);
			_tempRatioMiddleH = (_h - _tempTop - _tempBottom) / _rect.height;
			
			if (_tempRatioSidesW > 1) _tempRatioSidesW = 1;
			if (_tempRatioMiddleW < 0) _tempRatioMiddleW = 0;
			if (_tempRatioSidesH > 1) _tempRatioSidesH = 1;
			if (_tempRatioMiddleH < 0) _tempRatioMiddleH = 0;
			
			//top left
			_tempMatrix.identity();
			_tempRect.x = 0;
			_tempRect.y = 0;
			_tempRect.width = _tempLeft * _tempRatioSidesW;
			_tempRect.height = _tempTop * _tempRatioSidesH;
			_tempMatrix.scale(_tempRatioSidesW, _tempRatioSidesH);
			newBD.draw(_originalBD, _tempMatrix, null, null, _tempRect);
			
			//bottom left
			_tempMatrix.identity();
			_tempRect.x = 0;
			_tempRect.y = _h - _tempBottom * _tempRatioSidesH;
			_tempRect.width = _tempLeft * _tempRatioSidesW;
			_tempRect.height = _tempBottom * _tempRatioSidesH;
			_tempMatrix.translate(0, -_rect.y -_rect.height)
			_tempMatrix.scale(_tempRatioSidesW, _tempRatioSidesH);
			_tempMatrix.translate(0, _h - _tempBottom * _tempRatioSidesH);
			newBD.draw(_originalBD, _tempMatrix, null, null, _tempRect);
			
			//top right
			_tempMatrix.identity();
			_tempRect.x = _w - _tempRight * _tempRatioSidesW;
			_tempRect.y = 0;
			_tempRect.width = _tempRight * _tempRatioSidesW;
			_tempRect.height = _tempTop * _tempRatioSidesH;
			_tempMatrix.translate( -_rect.x - _rect.width, 0)
			_tempMatrix.scale(_tempRatioSidesW, _tempRatioSidesH);
			_tempMatrix.translate(_w - _tempRight * _tempRatioSidesW, 0);
			newBD.draw(_originalBD, _tempMatrix, null, null, _tempRect);
			
			//bottom right
			_tempMatrix.identity();
			_tempRect.x = _w - _tempRight * _tempRatioSidesW;
			_tempRect.y = _h - _tempBottom * _tempRatioSidesH;
			_tempRect.width = _tempRight * _tempRatioSidesW;
			_tempRect.height = _tempBottom * _tempRatioSidesH;
			_tempMatrix.translate( -_rect.x - _rect.width, -_rect.y -_rect.height)
			_tempMatrix.scale(_tempRatioSidesW, _tempRatioSidesH);
			_tempMatrix.translate(_w - _tempRight * _tempRatioSidesW, _h - _tempBottom * _tempRatioSidesH);
			newBD.draw(_originalBD, _tempMatrix, null, null, _tempRect);
			
			if (_tempRatioMiddleH > 0)
			{
				//left middle
				_tempMatrix.identity();
				_tempRect.x = 0;
				_tempRect.y = _tempTop;
				_tempRect.width = _tempLeft * _tempRatioSidesW;
				_tempRect.height = _h - _tempTop - _tempBottom;
				_tempMatrix.translate(0, -_tempTop)
				_tempMatrix.scale(_tempRatioSidesW, _tempRatioMiddleH);
				_tempMatrix.translate(0, _tempTop);
				newBD.draw(_originalBD, _tempMatrix, null, null, _tempRect);
				
				//right middle
				_tempMatrix.identity();
				_tempRect.x = _w - _tempRight * _tempRatioSidesW;
				_tempRect.y = _tempTop;
				_tempRect.width = _tempRight * _tempRatioSidesW;
				_tempRect.height = _h - _tempTop - _tempBottom;
				_tempMatrix.translate(-_rect.x - _rect.width, -_tempTop)
				_tempMatrix.scale(_tempRatioSidesW, _tempRatioMiddleH);
				_tempMatrix.translate(_w - _tempRight * _tempRatioSidesW, _tempTop);
				newBD.draw(_originalBD, _tempMatrix, null, null, _tempRect);
			}
			
			if (_tempRatioMiddleW > 0)
			{
				//top middle
				_tempMatrix.identity();
				_tempRect.x = _tempLeft;
				_tempRect.y = 0;
				_tempRect.width = _w - _tempLeft - _tempRight;
				_tempRect.height = _tempTop * _tempRatioSidesH;
				_tempMatrix.translate( -_rect.x -_rect.width, 0)
				_tempMatrix.scale(_tempRatioMiddleW, _tempRatioSidesH);
				_tempMatrix.translate(_w - _tempRight * _tempRatioSidesW, 0);
				newBD.draw(_originalBD, _tempMatrix, null, null, _tempRect);
				
				//bottom middle
				_tempMatrix.identity();
				_tempRect.x = _tempLeft;
				_tempRect.y = _h - _tempBottom * _tempRatioSidesH;
				_tempRect.width = _w - _tempLeft - _tempRight;
				_tempRect.height = _tempBottom * _tempRatioSidesH;
				_tempMatrix.translate( -_rect.x -_rect.width, -_rect.y -_rect.height)
				_tempMatrix.scale(_tempRatioMiddleW, _tempRatioSidesH);
				_tempMatrix.translate(_w - _tempRight * _tempRatioSidesW, _h - _tempBottom * _tempRatioSidesH);
				newBD.draw(_originalBD, _tempMatrix, null, null, _tempRect);
			}
			
			if (_tempRatioMiddleH > 0 && _tempRatioMiddleW > 0)
			{
				//center
				_tempMatrix.identity();
				_tempRect.x = _tempLeft;
				_tempRect.y = _tempTop;
				_tempRect.width = _w - _tempLeft - _tempRight;
				_tempRect.height = _h - _tempTop - _tempBottom;
				_tempMatrix.translate( -_tempLeft, -_tempTop)
				_tempMatrix.scale(_tempRatioMiddleW, _tempRatioMiddleH);
				_tempMatrix.translate(_tempLeft, _tempTop);
				newBD.draw(_originalBD, _tempMatrix, null, null, _tempRect);
			}
			
			newBD.unlock();
			super.bitmapData = newBD;
		}
	}
}